package com.my.action;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.RequestContext;

import com.my.annotation.SystemErrorLog;
import com.my.annotation.SystemOperatorLog;
import com.my.constant.Common;
import com.my.constant.ErrorCode;
import com.my.entity.Employee;
import com.my.entity.LeaveBill;
import com.my.entity.ResponseData;
import com.my.entity.WorkflowBean;
import com.my.exception.BusinessException;
import com.my.service.IWorkflowService;
import com.my.service.LeaveBillService;

@Controller
@RequestMapping(value="/workflow")
public class WorkflowAction {
	private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
	@Resource
	private IWorkflowService workflowService;
	@Resource
	private LeaveBillService leaveBillService;

	/**
	 * 发布流程
	 * @return
	 */
	@RequestMapping(value = "upload")
	@SystemOperatorLog(description="发布流程信息")
	public String upload(
			@RequestParam(value = "file", required = false) MultipartFile file,
			HttpServletRequest request, String fileNickName) {
		String path = request.getSession().getServletContext()
				.getRealPath("upload");
		String fileName = file.getOriginalFilename();
		File targetFile = new File(path, fileName);
		if (!targetFile.exists()) {
			targetFile.mkdirs();
		}
		try {
			file.transferTo(targetFile);
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			workflowService.saveNewDeploye(targetFile, fileNickName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "redirect:deploy.do";
	}

	/**
	 * 删除部署信息
	 */
	@RequestMapping(value = "delete_deploy")
	@SystemOperatorLog(description="删除部署信息")
	public String delDeployment(String id) {
		workflowService.deleteProcessDefinitionByDeploymentId(id);
		return "redirect:deploy.do";
	}

	/**
	 * 查看流程图
	 * 
	 * @throws Exception
	 */
	@RequestMapping(value = "view_img")
	public void viewImage(HttpServletResponse response, String deploymentId,
			String imageName) {
		// 2：获取资源文件表（act_ge_bytearray）中资源图片输入流InputStream
		InputStream in = workflowService.findImageInputStream(deploymentId,
				imageName);
		try {
			// 3：从response对象获取输出流
			OutputStream out = response.getOutputStream();
			// 4：将输入流中的数据读取出来，写到输出流中
			for (int b = -1; (b = in.read()) != -1;) {
				out.write(b);
			}
			out.close();
			in.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 点击申请请假的时候执行
	 * @param id
	 * @param request
	 * @return
	 * @throws BusinessException 
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping(value = "start_process")
	@SystemOperatorLog(description="启动流程")
	@SystemErrorLog(description="启动流程失败")
	public @ResponseBody ResponseData startProcess(Long id, HttpServletRequest request) throws BusinessException {
		// 更新请假状态，启动流程实例，让启动的流程实例关联业务
		Employee employee = (Employee) request.getSession().getAttribute(
				Common.CURRENT_OPERATOR.getValue());
		
		RequestContext requestContext = new RequestContext(request);
		try {
			workflowService.saveStartProcess(id, employee.getName());
			return new ResponseData(ErrorCode.SUCCESS,ErrorCode.SUCCESS.getDesc(),null,false,null);
		} catch (Exception e) {
			throw new BusinessException(ErrorCode.DEPLOY_ID_NOT_EXIST, requestContext.getMessage("DEPLOY_ID_NOT_EXIST"),new BusinessException());
			//return new ResponseData(ErrorCode.SUCCESS,ErrorCode.SUCCESS.getDesc(),null,false,null);
		}
	}
	
	/**
	 * 办理任务的时候先到这里，得到formData.getFormKey();  跳转到audit.do
	 * @param taskId
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "view_task_form")
	public String viewTaskForm(String taskId, HttpServletRequest request) {
		// 获取任务表单中任务节点的url连接
		String url = "http://localhost:8888/simple_activiti/workflow/"+workflowService.findTaskFormKeyByTaskId(taskId);
		// workflowAction_audit.action
		url += "?taskId=" + taskId;
		return "redirect:" + url;
	}

	// 准备表单数据
	@RequestMapping(value = "audit")
	public String audit(WorkflowBean workflowBean, HttpServletRequest request) {
		// 获取任务ID
		String taskId = workflowBean.getTaskId();
		/** 一：使用任务ID，查找请假单ID，从而获取请假单信息 */
		LeaveBill leaveBill = workflowService.findLeaveBillByTaskId(taskId);
		request.setAttribute("leaveBill", leaveBill);
		/**
		 * 二：已知任务ID，查询ProcessDefinitionEntiy对象，从而获取当前任务完成之后的连线名称，并放置到List<String
		 * >集合中
		 */
		List<String> outcomeList = workflowService
				.findOutComeListByTaskId(taskId);
		request.setAttribute("outcomeList", outcomeList);
		/** 三：查询所有历史审核人的审核信息，帮助当前人完成审核，返回List<Comment> */
		List<Comment> commentList = workflowService.findCommentByTaskId(taskId);
		request.setAttribute("commentList", commentList);
		request.setAttribute("taskId", taskId);
		return "workflow/task_form";
	}

	/**
	 * 提交任务
	 */
	@RequestMapping(value = "submit_task")
	@SystemOperatorLog(description="办理任务")
	public String submitTask(WorkflowBean workflowBean,HttpServletRequest request) {
		Employee employee=(Employee) request.getSession().getAttribute(Common.CURRENT_OPERATOR.getValue());
		workflowService.saveSubmitTask(workflowBean,employee.getName());
		return "redirect:http://localhost:8888/simple_activiti/workflow/personal_task.do";
	}

	/**
	 * 查看当前流程图（查看当前活动节点，并使用红色的框标注）
	 */
	@RequestMapping(value = "view_curr_img")
	public String viewCurrentImage(String taskId, HttpServletRequest request) {
		/** 一：查看流程图 */
		// 1：获取任务ID，获取任务对象，使用任务对象获取流程定义ID，查询流程定义对象
		ProcessDefinition pd = workflowService
				.findProcessDefinitionByTaskId(taskId);
		request.setAttribute("deploymentId", pd.getDeploymentId());
		request.setAttribute("imageName", pd.getDiagramResourceName());
		/** 二：查看当前活动，获取当期活动对应的坐标x,y,width,height，将4个值存放到Map<String,Object>中 */
		Map<String, Object> map = workflowService.findCoordingByTask(taskId);
		request.setAttribute("acs", map);
		return "workflow/image";
	}

	// 查看历史的批注信息
	@RequestMapping(value = "view_his_comm")
	public String viewHisComment(WorkflowBean workflowBean,
			HttpServletRequest request) {
		// 获取清单ID
		Long id = workflowBean.getId();
		// 1：使用请假单ID，查询请假单对象，将对象放置到栈顶，支持表单回显
		LeaveBill leaveBill = leaveBillService.selectByPrimaryKey(id);
		// 2：使用请假单ID，查询历史的批注信息
		List<Comment> commentList = workflowService
				.findCommentByLeaveBillId(id);
		request.setAttribute("commentList", commentList);
		request.setAttribute("leaveBill", leaveBill);
		return "workflow/task_form_his";
	}
	
	/**
	 * 查看部署信息
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "deploy")
	public String gotoDeploy(HttpServletRequest request) {
		// 1:查询部署对象信息，对应表（act_re_deployment）
		List<Deployment> deploymentList = workflowService.findDeploymentList();
		// 2:查询流程定义的信息，对应表（act_re_procdef）
		List<ProcessDefinition> processDefinitionList = workflowService
				.findProcessDefinitionList();
		// 放置到上下文对象中
		request.setAttribute("deploymentList", deploymentList);
		request.setAttribute("processDefinitionList", processDefinitionList);
		return "workflow/deploy";
	}
	

	/**
	 * 查看个人任务列表
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "personal_task")
	public String gotoPersonalTask(HttpServletRequest request) {
		// 1：从Session中获取当前用户名
		Employee employee = (Employee) request.getSession().getAttribute(
				Common.CURRENT_OPERATOR.getValue());
		String name = employee.getName();
		// 2：使用当前用户名查询正在执行的任务表，获取当前任务的集合List<Task>
		List<Task> taskList = workflowService.findTaskListByName(name);
		request.setAttribute("taskList", taskList);
		return "workflow/personal_task";
	}
	
	
	
	@RequestMapping(value = "personal_task_total")
	public @ResponseBody ResponseData<Integer> totalTask(HttpServletRequest request){
		try {
			//查到当前用户有多少任务，便于显示
			Employee employee = (Employee) request.getSession().getAttribute(
					Common.CURRENT_OPERATOR.getValue());
			int totalTask=workflowService.findTaskListByName(employee.getName()).size();
			List<Integer> totalTaskList=new ArrayList<Integer>();
			totalTaskList.add(totalTask);
			return new ResponseData<Integer>(ErrorCode.SUCCESS,
					ErrorCode.SUCCESS.getDesc(),totalTaskList,false,null);
		} catch (Exception e) {
			e.printStackTrace();
			return new ResponseData<Integer>(ErrorCode.FAUILURE,
					ErrorCode.FAUILURE.getDesc(), null, true,null);
		}
	}
	
	
}
